package http

import (
	"fmt"
	"io"
	"log"
	"net"
	"time"
)

// UploadNotifyMessage 上传通知消息（轻量级）
type UploadNotifyMessage struct {
	RequestID string
	TunnelID  string
}

// Encode 编码上传通知消息
// 格式: UPLOAD_NOTIFY\r\nRequestID: xxx\r\nTunnelID: xxx\r\n\r\n
func (m *UploadNotifyMessage) Encode() ([]byte, error) {
	message := fmt.Sprintf("UPLOAD_NOTIFY\r\nRequestID: %s\r\nTunnelID: %s\r\n\r\n",
		m.RequestID, m.TunnelID)
	return []byte(message), nil
}

// DecodeUploadNotifyMessage 解码上传通知消息
func DecodeUploadNotifyMessage(reader io.Reader) (*UploadNotifyMessage, error) {
	// 读取第一行: UPLOAD_NOTIFY
	firstLine := make([]byte, 14) // "UPLOAD_NOTIFY\r"
	if _, err := io.ReadFull(reader, firstLine); err != nil {
		return nil, fmt.Errorf("读取消息类型失败: %v", err)
	}

	if string(firstLine[:13]) != "UPLOAD_NOTIFY" {
		return nil, fmt.Errorf("无效的消息类型: %s", firstLine)
	}

	// 读取剩余内容（简化：假设格式正确）
	// 真实场景应该更严格地解析
	remaining := make([]byte, 1024)
	n, err := reader.Read(remaining)
	if err != nil && err != io.EOF {
		return nil, fmt.Errorf("读取消息内容失败: %v", err)
	}

	content := string(remaining[:n])

	// 简单解析RequestID和TunnelID
	// 格式: \nRequestID: xxx\r\nTunnelID: yyy\r\n\r\n
	msg := &UploadNotifyMessage{}

	// 这里简化解析，实际应该用正则或更严格的解析
	if idx := findHeader(content, "RequestID:"); idx >= 0 {
		start := idx + 11 // "RequestID: "的长度
		end := start
		for end < len(content) && content[end] != '\r' && content[end] != '\n' {
			end++
		}
		msg.RequestID = content[start:end]
	}

	if idx := findHeader(content, "TunnelID:"); idx >= 0 {
		start := idx + 10 // "TunnelID: "的长度
		end := start
		for end < len(content) && content[end] != '\r' && content[end] != '\n' {
			end++
		}
		msg.TunnelID = content[start:end]
	}

	return msg, nil
}

// findHeader 查找头部字段
func findHeader(content string, header string) int {
	for i := 0; i < len(content)-len(header); i++ {
		if content[i:i+len(header)] == header {
			return i
		}
	}
	return -1
}

// SendUploadNotification 发送上传通知给客户端，并通过HTTP/2混合模式接收响应
// 注意：这个函数需要从 TunnelManager 调用，因为需要访问 quicServer
type UploadNotificationSender interface {
	SendRequestToClient(tunnelID string, requestID string, data []byte, browserConn net.Conn) error
}

// SendUploadNotification 发送上传通知的辅助函数
func SendUploadNotification(sender UploadNotificationSender, tunnelID string, requestID string, browserConn net.Conn) error {
	// 创建上传通知消息（轻量级，只包含元数据）
	notification := &UploadNotifyMessage{
		RequestID: requestID,
		TunnelID:  tunnelID,
	}

	// 编码消息
	messageData, err := notification.Encode()
	if err != nil {
		return fmt.Errorf("编码通知失败: %v", err)
	}

	log.Printf("📤 [上传通知] 发送QUIC通知: RequestID=%s, TunnelID=%s, Size=%d bytes",
		requestID[:8]+"...", tunnelID[:8]+"...", len(messageData))

	// 🔥🔥🔥 关键架构变更：使用HTTP/2混合模式接收响应（与原有逻辑一致）
	// 1. 注册pending响应（客户端将通过HTTP/2发送）
	// 2. 通过QUIC发送通知
	// 3. 等待HTTP/2响应
	// 4. 转发给浏览器

	// 🔥🔥🔥 关键架构变更：让SendRequestToClient去处理HTTP/2响应等待
	// 问题：如果我们先注册pending response，然后调用SendRequestToClient，
	//      SendRequestToClient内部也会注册，导致第二次注册覆盖第一次
	// 解决：直接调用SendRequestToClient，它会内部处理HTTP/2响应等待和转发

	startTime := time.Now()
	err = sender.SendRequestToClient(tunnelID, requestID, messageData, browserConn)
	sendDuration := time.Since(startTime)

	if err != nil {
		log.Printf("❌ [上传通知] 发送通知并等待响应失败: %v, 耗时=%.2fs",
			err, sendDuration.Seconds())
		return fmt.Errorf("上传通知处理失败: %v", err)
	}

	log.Printf("✅ [上传通知] 通知发送并响应完成: RequestID=%s, 耗时=%.2fs",
		requestID[:8]+"...", sendDuration.Seconds())
	return nil
}
